<?php

namespace app\mini\model;

use Kingdee\Kingdee;
use think\facade\Db;
use app\crm\model\Customer as CustomerModel;
use app\shop\model\Goods as GoodsModel;
use app\shop\model\GoodsPrice as GoodsPriceModel;
use app\common\traits\ActionRecordTrait;
use think\Model;

class Order extends Model
{
	use ActionRecordTrait;

    /**
     * 表名
     * @var string
     */
    protected $name = 'shop_order';
    protected $deleteTime = 'deleted_at';
    protected $defaultSoftDelete = 0;

    /**
     * 获取订单列表
     * @param  array $request 请求参数
     * @return array
     * @author SL
     * @create 2021-06-1
     */
    public function getDataList($request)
    {
        try {
            $uid 	 = $request['customer_id'] ?? 0;
            if(!$uid)
            {
            	return ['error' => '您还未认证,请先认证'];
            }
            $where   = [];
            $status  = isset($request['status']) && intval($request['status']) ? intval($request['status']) : 0; // 状态：0-全部 1-待支付 2-待发货 3-待收货 4-已收货
            switch ($status) {
	           	case '1':
	           		$where = [
	           			['status', '<>', 6],
	           			['is_pay', '=', 0]
	           		];
	           		break;
	           	case '2':
	           		$where = [
	           			['status', 'in', [0,1,2]],
                        ['is_pay', '=', 1]
	           		];
	           		break;
	           	case '3':
	           		$where = [
	           			['status', '=', 3]
	           		];
	           		break;
	           	case '4':
	           		$where = [
	           			['status', 'in', [4,5]]
	           		];
	           		break;
	           	default:
	           		$where = [];
	           		break;
            }
            $where[] = ['uid', '=', $uid];

            // 订单列表
            $field = ['id,order_no,status,is_pay,pay_amount'];
            $list  = Db::name('shop_order')->field($field)->where($where)->limit(($request['page'] - 1) * $request['limit'], $request['limit'])->order('id DESC')->select()->toArray();
            $dataCount = Db::name('shop_order')->where($where)->count();
           
            // 订单商品
            $orderIdArr = array_column($list, 'id');
            $og_where = [
                ['og.order_id', 'in', $orderIdArr]
            ];
            $og_field = ['og.order_id,min(og.id) as order_goods_id,sum(og.pay_price * og.number) as order_goods_price,og.goods_name,og.item_name,og.unit_name,og.number,g.image'];
            $orderGoodsList = Db::name('shop_order_goods')
            			->alias('og')
                		->join(['shrimp_shop_goods' =>'g'],'og.goods_id=g.id')
                        ->field($og_field)
                        ->where($og_where)
                        ->group('og.order_id')->select()->toArray();
            foreach ($orderGoodsList as $key => $value) 
            {
                $orderGoodsList[$key]['image'] = config('app.img_url').$value['image'];
            }
            $orderGoodsList = array_column($orderGoodsList, null, 'order_id');

            if ($list) {
                foreach($list as &$v){
                    $v['goods'] = isset($orderGoodsList[$v['id']]) ? $orderGoodsList[$v['id']] : [];
                }
            }

            $data              = [];
            $data['list']      = $list;
            $data['dataCount'] = $dataCount ?? 0;
            return ['data' => $data];
        } catch (\Exception $e) {
            return ['error' => $e->getMessage()];
        }
    }

    /**
     * 订单详情
     * @param array $request
     * @return array
     * @author SL
     * @create 2021-06-02
     */
    public function getDataDetail($request)
    {
        try {
            $id = $request['order_id'] ?? 0;
            if(!$id){
                return ['error' => '请传入订单id'];
            }
            $detail = [];
            $list =[];
            $field = ['o.*', 'c.name as customer_name'];
            $detail = $this
                ->alias('o')
                ->join(['shrimp_crm_customer' =>'c'],'o.uid=c.customer_id')
                ->where('o.id',$id)
                ->field($field)->find();

            if($detail){
                // 时间转化
                $detail['pay_time'] = $detail['pay_time'] ? date('Y-m-d H:i:s', $detail['pay_time']) : '';
                $detail['send_time'] = $detail['send_time'] ? date('Y-m-d H:i:s', $detail['send_time']) : '';
                $detail['receive_time'] = $detail['receive_time'] ? date('Y-m-d H:i:s', $detail['receive_time']) : '';
                $detail['complete_time'] = $detail['complete_time'] ? date('Y-m-d H:i:s', $detail['complete_time']) : '';
                $detail['cancel_time'] = $detail['cancel_time'] ? date('Y-m-d H:i:s', $detail['cancel_time']) : '';

                // 收货地址
                $region = Db::name('shop_region')->column('name','id');
                $detail['province_name'] = $region[$detail['province']];
                $detail['city_name'] = $region[$detail['city']];
                $detail['district_name'] = $region[$detail['district']];

                $allOrderGoods = Db::name('shop_order_goods')->field('number')->where('order_id', $id)->select()->toArray();
                // 订单商品数量
                $detail['total_number'] = array_sum(array_map(function($val){return $val['number'];}, $allOrderGoods));

                // 订单商品
                $detail['goodsList'] = [];
                $og_field = ['og.id', 'og.goods_id', 'og.number', 'og.goods_price', 'og.pay_price', 'og.goods_name', 'og.kingdee_code', 'og.item_name', 'og.unit_name', 'g.image'];
                $list = Db::name('shop_order_goods')
                    ->alias('og')
                    ->join(['shrimp_shop_goods' =>'g'],'og.goods_id=g.id')
                    ->where('og.order_id', $id)
                    ->order('og.id desc')
                    ->field($og_field)
                    ->select()
                    ->toArray();
                foreach ($list as $key => $value) 
                {
                    $list[$key]['image'] = config('app.img_url').$value['image'];
                }
            }
            else{
                return ['error' => '订单不存在'];
            }

            if ($list) {
                $detail['goodsList'] = $list;
            }

            return ['data' => $detail];
        } catch (\Exception $e) {
            return ['error' => $e->getMessage()];
        }
    }

    /**
     * 确认订单
     * @param  array $request 请求参数
     * @return array
     * @author SL
     * @create 2021-07-09
     */
    public function confirmData($request)
    {
         try {
            $customerId = $request['customerId'] ?? 0;
            $list = isset($request['list']) && $request['list'] ? $request['list'] : [];
            if(!$customerId)
            {
                return ['error' => '您还未认证,请先认证'];
            }
            if(!$list){
                return ['error' => '参数错误'];
            }
            $goodsIdArr = array_column($list, 'goods_id');
            $paramArr['user_id'] = $customerId;
            $paramArr['where'] = [['g.status','=',1],['g.is_standard_product','=',1],['g.id','in',$goodsIdArr]];
            $paramArr['field'] = ['g.id', 'g.name', 's.price','s.small_unit_price' ,'g.image','g.thumb_image','s.id as sku_id','s.item_id','s.unit_id','s.kingdee_code','s.is_small_sales','s.is_big_sales'];
            $goodsData = (new GoodsModel())->getDataList($paramArr);
            $gl = $goodsData['list'];
            $gl = array_column($gl,null,'id');
            $gls = [];  // 初始化列表
            $allnum = $totalAmount = 0;
            foreach ($list as $kc => $vc){
                if( !isset($gl[$vc['goods_id']]) ){  // 商品不存在
                    continue;
                }
                $goods = $gl[$vc['goods_id']];
                $goods['spec_list'] = array_column($goods['spec_list'],null,'unit_code');
                if( !isset($goods['spec_list'][$vc['unit_code']]) ){
                    continue;
                }
                $listItem = [
                    'id'  =>  $vc['goods_id'],
                    'name'    =>  $goods['name'],
                    'thumb_image' =>  $goods['thumb_image'],
                    'image'   =>  $goods['image'],
                    'item_id' =>  $goods['item_id'],
                    'unit_id' =>  $goods['unit_id'],
                    'sku_id'  =>  $goods['sku_id'],
                    'kingdee_code'  =>  $goods['kingdee_code'],
                    'price'   =>  $goods['spec_list'][$vc['unit_code']]['price'],
                    'customer_price'   =>  $goods['spec_list'][$vc['unit_code']]['customer_price'],
                    'unit_name'  =>  $goods['spec_list'][$vc['unit_code']]['unit_name'],
                    'item_name'  =>  $goods['spec_list'][$vc['unit_code']]['item_name'],
                    'unit_code'  =>  $goods['spec_list'][$vc['unit_code']]['unit_code'],
                    'num'        =>  $vc['num'],
                ];
                $totalAmount += $goods['spec_list'][$vc['unit_code']]['customer_price'] * 100 * $vc['num'];
                $allnum += $vc['num'];
                $gls[] = $listItem;
            }
            // 收货信息 
            $field = ['bind_id', 'contacter', 'telephone', 'province', 'city', 'district', 'address'];
            $delivery = Db::name('crm_customer_bind')
                            ->where('customer_id', $customerId)
                            ->field($field)
                            ->find();
            if( is_null($delivery) ){
                $delivery['address'] = '';
            }
            // 处理省市区返回数据
            $region = Db::name('shop_region')->where('id','in',[(int)$delivery['province'],(int)$delivery['city'],(int)$delivery['district']])->column('name', 'id');
            $delivery['province_name'] = !empty($delivery['province']) ? $region[$delivery['province']] : '';
            $delivery['city_name'] = !empty($delivery['city']) ? $region[$delivery['city']] : '';
            $delivery['district_name'] = !empty($delivery['district']) ? $region[$delivery['district']] : '';
            $data['allnum'] = $allnum;
            $data['total_amount'] = number_format($totalAmount / 100,2);
            $gls = array_values($gls);
            $data['list'] = $gls;
            $data['delivery'] = $delivery;
            return ['data' => $data];
         } catch (\Exception $e) {
             return ['error' => $e->getMessage()];
         }
    }

    /**
     * 创建订单
     * @param  array $request 请求参数
     * @return array
     * @author SL
     * @create 2021-06-03
     */
    public function addData(array $request): array
    {
        Db::startTrans();
        try {
            $customerModel = new CustomerModel();
            $customerInfo = $customerModel->getTeamInfo($request['uid']);
            if(!isset($customerInfo['business_trans_user_id']) || empty($customerInfo['business_trans_user_id']) || !isset($customerInfo['leads_touch_user_id']) || empty($customerInfo['leads_touch_user_id']))
            {
                throw new \Exception('尚未对接业务员，不能创建订单');
            }
            if(!isset($customerInfo['bind_house_code']) || empty($customerInfo['bind_house_code']))
            {
                throw new \Exception('仓库信息不完善，请联系业务员');
            }

            $time = time();
            $list = $request['list'];
            $delivery = $request['delivery'];
            // 验证商品价格
            $goodsIdArr = array_column($list, 'id');
            $paramArr['user_id'] = $request['uid'];
            $paramArr['where'] = [['g.status','=',1],['g.is_standard_product','=',1],['g.id','in',$goodsIdArr]];
            $paramArr['field'] = ['g.id', 'g.name', 's.price','s.small_unit_price' ,'g.image','g.thumb_image','s.item_id','s.unit_id','s.is_small_sales','s.is_big_sales'];
            $goodsData = (new GoodsModel())->getDataList($paramArr);
            $gl = $goodsData['list'];
            $gl = array_column($gl,null,'id');
            $totalAmount = 0;
            foreach ($list as $k => $v) {
                $goods = $gl[$v['id']]??[];
                if( empty($goods) ){
                    throw new \Exception('商品不存在或已下架');
                }
                $goods['spec_list'] = array_column($goods['spec_list'],null,'unit_code');
                if( $v['customer_price'] != $goods['spec_list'][$v['unit_code']]['customer_price'] ){
                    throw new \Exception('商品【' . $v['name'] . '】价格有变动；');
                }
                $totalAmount += $v['customer_price'] * 100 * $v['num'];
            }
            $totalAmount = number_format($totalAmount / 100,2);
            
            // 验证
            $data = [
                // 'is_first'     => trim($request['is_first']), // 首批单 0-否 1-是
                'leads_owner_id'   => $customerInfo['leads_owner_user_id'], // 线索负责人id
                'leads_touch_id'   => $customerInfo['leads_touch_user_id'], // 线索触达人id
                'customer_owner_id'=> $customerInfo['customer_owner_user_id'], // 客户负责人id
                'customer_trans_id'=> $customerInfo['customer_trans_user_id'], // 客户转化人id
                'business_owner_id'=> $customerInfo['business_owner_user_id'], // 商机负责人id
                'business_trans_id'=> $customerInfo['business_trans_user_id'], // 商机转化人id
                'uid'          => $request['uid'], // 客户
                'house_id'     => $customerInfo['bind_house_code'], // 仓库

                'order_no'     => $this->getOrderNo(), // 订单号
                'consignee'    => trim($delivery['contacter']), // 收货人
                'mobile'       => trim($delivery['telephone']), // 收货人手机号
                'province'     => (int) $delivery['province'], // 省
                'city'         => (int) $delivery['city'], // 市
                'district'     => (int) $delivery['district'], // 区
                'address'      => trim($delivery['address']), // 收货地址
                'description'  => trim($request['description']), // 订单备注
                'create_time'  => $time, // 创建时间
                'order_amount' => $totalAmount, // 订单总金额
                'pay_amount'   => $totalAmount, // 支付金额
            ];
            $orderId = Db::name('shop_order')->insertGetId($data);
            if (!$orderId) {
                throw new \Exception('创建订单失败');
            }
            
            $orderGoodsList = [];   // 订单商品集合初始化
            $guArr = [];  // 预删除购物车中的商品集合
            foreach ($list as $k => &$v) {
                $item = [
                    'order_id'      =>  $orderId,
                    'number'        =>  $v['num'],
                    'pay_price'     =>  $v['customer_price'],
                    'goods_price'   =>  $v['price'],
                    'goods_id'      =>  $v['id'],
                    'goods_name'    =>  $v['name'],
                    'kingdee_code'  =>  $v['kingdee_code'],
                    'sku_id'        =>  $v['sku_id'],
                    'item_id'       =>  $v['item_id'],
                    'item_name'     =>  $v['item_name'],
                    'unit_id'       =>  $v['unit_id'],
                    'unit_name'     =>  $v['unit_name'],
                    'unit_code'     =>  $v['unit_code'],
                    'uid'           =>  $request['uid'],
                    'image'         =>  $v['image']??'',
                    'create_time'   =>  time()
                ];
                $orderGoodsList[] = $item; 
                $guArr[] = ['goodsId'=>$item['goods_id'],'unitCode'=>$item['unit_code']]; 
            }

            $insertNum = Db::name('shop_order_goods')->insertAll($orderGoodsList);
            if ($insertNum <= 0) {
                throw new \Exception('创建订单商品失败');
            }
            
            // 购物车结算,更改商品状态
            if($request['submit_type'] == 1)
            {
                (new \app\mini\controller\Cart(app()))->delto($guArr);
            }

            // 订单取消队列
            $cancel_order_time = Db::name('admin_setting')->where(['name' => 'cancel_order_time'])->value('value');
            $queueData = [];
            $queueData['queue_type'] = 'cancel_order';
            $queueData['order_id']   = $orderId;
            $queueData['delay_time'] = $cancel_order_time;
            add_think_queue( $queueData );

            // 添加操作记录
            $customer_name = Db::name('crm_customer')->where(['customer_id' => $request['uid']])->value('name');
            $goods_name = array_column($orderGoodsList, 'name');
            $goods_name_str = implode('|', $goods_name);
            $content = '创建订单：创建【' . $customer_name . '】的【微信小程序】订单，订单号：【' . $data['order_no'] . '】，商品：【' . $goods_name_str . '】';
            $code = $data;
            $code['orderGoodsList']  = $orderGoodsList;
            $this->addActionRecord($request['uid'],'min_shop_order_create',$orderId,$content,'min','order',json_encode($code, JSON_UNESCAPED_UNICODE));

            Db::commit();
            $res = [
                'order_id'   => $orderId,
                'order_no'   => $data['order_no'],
                'pay_amount' => $totalAmount

                // 'pay_amount' => bcadd($total_amount, 0, 2)
            ];
            return ['error' => '创建成功', 'data' => $res];
        } catch (\Exception $e) {
            Db::rollback();
            return ['error' => $e->getMessage()];
        }
    }

    /**
     * 修改订单状态
     * 作废、确认收货
     * @param array $request 请求参数
     * @return bool
     * @author SL
     * @create 2021-06-08
     */
    public function checkOrderData($request)
    {
        $id = $request['order_id'] ?? 0;
        $status = $request['status'] ?? 0;
        if (!$id) {
            return ['error' => '参数错误'];
        }

        $order = Db::name('shop_order')->where('id',$id)->find();
        if(!$order)
        {
        	return ['error' => '订单不存在'];
        }

        // 订单确认收货
        if($status == 4)
        {
            // 不是已发货状态,不能确认收货
            if($order['status'] != 3)
            {
            	return ['error' => '订单不能确认收货,请联系业务员'];
            }
            $content = '客户确认收货成功';
            $data['receive_time'] = time(); // 收货时间
            if($order['is_pay'] == 1)
            {
                $status = 5;
                $content .= '，支付状态【' . $order['is_pay'] . '】';
                $data['complete_time'] = time(); // 完成时间
            }
        }
        // 订单作废
        else if($status == 6)
        {
            // 不是 待审核 或 已审核状态,不能作废
            if(!in_array($order['status'], [0,1,2]))
            {
            	return ['error' => '订单不能作废,请联系业务员'];
            }
            $content = '客户作废订单成功';
            $data['cancel_time'] = time(); // 作废时间
        }
        else{
        	return ['error' => '参数错误'];
        }
        

        try {
            $arr = [0=>'待审核',1=>'已审核',2=>'已下推',3=>'已发货',4=>'已收货',5=>'已完成',6=>'已作废'];
            $content .= '，状态：【' . $arr[$order['status']] . '】修改为【' . $arr[$status] . '】';
            
            $data['status'] = $status; // 订单状态：0.待审核 1.已审核,2.已下推,3.已发货,4.已收货,5已完成,6.已作废
            $data['update_time'] = time();
            $bool = Db::name('shop_order')->where(['id'=>$id])->update($data);
            if ($bool !== false) {
                // 添加操作记录
                $this->addActionRecord($order['uid'], 'min_shop_order_check', $id, $content, 'min', 'order');
                return ['error' => '操作成功', 'data' => []];
            }
        } catch (\Exception $e) {
            return ['error' => $e->getMessage()];
        }
        return ['error' => '操作失败'];
    }

    /**
     * 生成订单号
     * @param  array $request 请求参数
     * @return String
     * @author SL
     * @create 2021-06-03
     */
    public function getOrderNo()
    {
        $order_sn = null;
        // 保证不会有重复订单号存在
        while(true){
            $order_sn = date('YmdHis').rand(1000,9999); // 订单编号
            $order_sn_count = DB::name('shop_order')->where('order_no', $order_sn)->count();
            if($order_sn_count == 0)
                break;
        }
        return $order_sn;
    }

    /**
     * 支付
     * @param  array $request 请求参数
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-07-07 16:14
     */
    public function payOrder(array $request): array
    {
        try {
            $orderNo    = isset($request['order_no']) && trim($request['order_no']) ? trim($request['order_no']) : '';
            $customerId = isset($request['customer_id']) && trim($request['customer_id']) ? trim($request['customer_id']) : '';
            if (!$orderNo || !$customerId) {
                return ['error' => '参数错误'];
            }

            // 订单信息
            $field     = ['id', 'uid', 'order_no', 'is_pay', 'pay_amount'];
            $orderInfo = $this->where('order_no', '=', $orderNo)->field($field)->find();
            if (!$orderInfo) {
                return ['error' => '订单不存在'];
            }
            if ($orderInfo['is_pay'] == 1) {
                return ['error' => '订单已支付'];
            }
            if ($orderInfo['pay_amount'] * 100 == 0) {
                return ['error' => '支付金额不正确'];
            }
            // 获取客户名称
            $customerName = Db::name('crm_customer')->where('customer_id', '=', $customerId)->value('name');

            // 调用微信支付
            $payData = [
                'order_no'    => $orderInfo['order_no'],
                'total_price' => $orderInfo['pay_amount'],
                'customer'    => $customerName
            ];
            $payResult = (new \app\mini\controller\Pay(app()))->takeOrder($payData);

            // 操作记录
            $dataArr = [
                'request'    => $request,
                'pay_data'   => $payData,
                'pay_return' => is_array($payResult) ? $payResult : [$payResult],
                'order_info' => $orderInfo
            ];
            $content = '微信小程序支付';
            $this->addActionRecord($orderInfo['uid'], 'min_shop_order_pay', $orderInfo['id'], $content, 'min', 'order', json_encode($dataArr, JSON_UNESCAPED_UNICODE));
            if (isset($payResult['code']) && $payResult['code'] == 1 && isset($payResult['paySign']) && $payResult['paySign']) {
                unset($payResult['code'], $payResult['msg'], $payResult['data'], $payResult['appId']);
                return ['error' => '调用支付成功', 'data' => $payResult];
            } else {
                return ['error' => $payResult['msg'] ?? '调用微信支付失败'];
            }
        } catch (\Exception $e) {
        }

        return ['error' => '调用微信支付失败'];
    }

    /**
     * 订单支付回调更新订单
     * @param  array $request 请求参数
     * @return bool
     * @author Mr.Liu Wuchen
     * @create 2021-07-08 9:52
     */
    public function payUpdateOrder(array $request): bool
    {
        $orderNo   = $request['orderid'] ?? '';
        $field     = ['id', 'uid', 'is_pay'];
        $orderInfo = $this->where('order_no', '=', $orderNo)->field($field)->find();
        if (!$orderInfo) {
            // 订单不存在
            return false;
        }
        try {
            $dataArr = $request;
            $content = '微信小程序支付--回调';
            $this->addActionRecord($orderInfo['uid'], 'min_shop_order_pay_notify', $orderInfo['id'], $content, 'min', 'notify', json_encode($dataArr, JSON_UNESCAPED_UNICODE));
            if ($orderInfo['is_pay'] == 1) {
                // 订单已支付
                return false;
            }

            // 更新订单状态
            $data = [
                'is_pay'             => 1,
                'customer_confirm'   => 1,
                'admin_user_confirm' => 1,
                'status'             => 1,
                'pay_no'             => $request['ordno'],
                'pay_time'           => time(),
                'notify_param'       => json_encode($request, JSON_UNESCAPED_UNICODE),
                'update_time'        => time()
            ];
            $bool = $this->where('id', '=', $orderInfo['id'])->update($data);
            if (!$bool) {
                // 更新订单失败
                return false;
            }

            // 重新赋值回调参数
            $data['notify_param'] = $request;
            // 支付成功推送金蝶
            $res = (new Kingdee())->send_order($orderInfo['id']);
            if ($res['code']) {
                $content = '微信小程序支付--回调--下推金蝶失败';
                $this->addActionRecord($orderInfo['uid'], 'min_shop_order_pay_notify_kingdee', $orderInfo['id'], $content, 'min', 'notify', json_encode($data, JSON_UNESCAPED_UNICODE));
            }

            $dataArr = $data;
            $content = '微信小程序支付--回调--更新订单状态已支付';
            $this->addActionRecord($orderInfo['uid'], 'min_shop_order_pay_notify', $orderInfo['id'], $content, 'min', 'notify', json_encode($dataArr, JSON_UNESCAPED_UNICODE));
            return true;
        } catch (\Exception $e) {
            $dataArr = [
                'notify_param' => $request,
                'order_info'   => $orderInfo
            ];
            $content = '微信小程序支付--回调--异常--' . $e->getMessage();
            $this->addActionRecord($orderInfo['uid'], 'min_shop_order_pay_notify', $orderInfo['id'], $content, 'min', 'notify', json_encode($dataArr, JSON_UNESCAPED_UNICODE));
        }

        return false;
    }

}